#ifndef RUNTIME_ATOMIC
#define RUNTIME_ATOMIC

#include "../prims/jni.h"
#include "stdint.h"

class Atomic
{

public:
    static void store(jlong store_value, volatile jlong *dest)
    {
        *dest = store_value;
    }

    static jlong load(volatile jlong *src)
    {
        return *src;
    }

    // https://www.cnblogs.com/mazhimazhi/p/17788592.html
    // 公众号：深入剖析Java虚拟机HotSpot
    static jint cmpxchg(jint exchange_value, volatile jint *dest, jint compare_value)
    {
        __asm__ volatile("lock;cmpxchgl %1,(%3)"
                         : "=a"(exchange_value)
                         : "r"(exchange_value), "a"(compare_value), "r"(dest)
                         : "cc", "memory");
        return exchange_value;
    }

     static jlong cmpxchg(jlong exchange_value, volatile jlong *dest, jlong compare_value)
    {
        __asm__ volatile("lock;cmpxchgq %1,(%3)"
                         : "=a"(exchange_value)
                         : "r"(exchange_value), "a"(compare_value), "r"(dest)
                         : "cc", "memory");
        return exchange_value;
    }

       
    static void* cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value)
    {
       return (void*)cmpxchg(
           (jlong)exchange_value,
           (volatile jlong*)dest,
           (jlong)compare_value);
    }


    static void inc(volatile jint *dest)
    {
        __asm__ volatile(
            "lock;addl $1,(%0)"
            :
            : "r"(dest)
            : "cc", "memory");
    }

    static void dec(volatile jint *dest)
    {
        __asm__ volatile(
            "lock;subl $1,(%0)"
            :
            : "r"(dest)
            : "cc", "memory");
    }

    static jint xchg(jint exchange_value, volatile jint *dest)
    {
        __asm__ volatile(
            "xchgl (%2),%0"
            : "=r"(exchange_value)
            : "0"(exchange_value), "r"(dest)
            : "memory");
        return exchange_value;    
    }
};

#endif